package org.medusa.network.tcp;

import java.util.HashMap;

import org.medusa.core.EventCallback;
import org.medusa.core.EventPump;
import org.medusa.log.ILog;
import org.medusa.packet.blob.BinaryPacket;

public abstract class TcpAsyncBinaryConnector<PacketType extends BinaryPacket>
		extends BaseTcpAsyncConnector<PacketType> {
	/*
	 * public static interface ProcCallback<PacketType> { int execute(PacketType
	 * pack); }
	 */

	private HashMap<Long, EventCallback<PacketType>> handler = new HashMap<Long, EventCallback<PacketType>>();;
	private long ev_del_protocol;
	private TcpAsyncBinaryConnector<PacketType> self = null;

	public TcpAsyncBinaryConnector(String name, ILog log, EventPump evp,
			int rcv_buf, int snd_buf, int idle_second) {

		super(name, log, evp, rcv_buf, snd_buf, idle_second);
		this.self = this;
		// this.handler = new HashMap<Long, EventCallback<PacketType>>();
		this.ev_del_protocol = this.GetEvp().AddEventListener(
				new EventCallback<Object[]>() {
					@Override
					public void execute(Object[] args) {
						long protocol_des = (Long) args[0];
						self.handler.remove(protocol_des);
					}

					@Override
					public void removed() {
						// TODO Auto-generated method stub
						
					}
				});
	}

	public boolean AddProtocol(long des, EventCallback<PacketType> proc) {
		boolean ret = !this.handler.containsValue(des);
		if (ret)
			this.handler.put(des, proc);
		return ret;
	}

	public boolean RemoveProtocol(long des) {
		boolean ret = this.handler.containsValue(des);
		if (ret)
			this.GetEvp().DispatchEvent(this.ev_del_protocol, des);
		return ret;
	}

	protected abstract void event_callback_UnknowPacketReceived(PacketType pack);

	@Override
	protected void event_callback_packet_received(PacketType pack) {
		if (pack != null) {
			EventCallback<PacketType> proc_func = this.handler.get(pack.Des());
			if (proc_func != null) {
				proc_func.execute(pack);
			} else {
				this.event_callback_UnknowPacketReceived(pack);
			}
		}

	}
}